函式 (Function)
C 函式參數 (Parameter)
在 C 語言中,函式參數通常是經由值傳遞,稱作 「傳值呼叫」 (Call by Value),這表示函式只接收到這變數的值。在函式內對參數進行的任何改變,都不會影響函式外的變數內容。
C 語言也有另一方式來傳遞參數,稱作 「傳址呼叫」 (Call by Address),使用 指標 (Pointers),將變數的記憶體位址當作參數傳遞給函式。這時,函式內計算的結果,會改變函式外的變數內容。
#include <stdio.h>
void addByValue(int x) { // call by value
x++;
}
void addByAddress(int* x) { // call by address
(*x)++;
}
int main() {
int num = 6;
addByValue(num);
printf("num: %d\n", num); // 呼叫函式後,num 依舊是 6
addByAddress(&num);
printf("num: %d\n", num); // 呼叫函式後,num 變成 7
return 0;
}
對於新手而言,我不建議一開始就要學習使用 指標 (pointer)。
如果只要改變單一變數,可以考慮使用函式的回傳值 (return value)。
如果要改變多個變數,可以考慮使用 陣列 (array) 當作函式的參數。
在C 程式碼中將陣列傳遞給一個函式時,實際上是將該陣列的第一個元素的記憶體地址傳遞給函式。
因此,在函式內對陣列進行的任何更改,都會改變函式外的陣列內容。
#include <stdio.h>
void addByArray(int[], int); // 函式的宣告
int main() {
int myArray[] = {2, 3, 4, 5, 6};
int size = 5;
addByArray(myArray, size);
for(int i = 0; i < size; i++) {
printf("%d, ", myArray[i]); // 輸出: 3, 4, 5, 6, 7,
}
return 0;
}
void addByArray(int arr[], int size) { // 函式的定義
for(int i = 0; i < size; i++) {
arr[i] += 1;
}
}
如前面例子 addByArray,C 語言的函式在使用時如果還沒有定義,就要在程式碼前面加上函式的宣告 (declaration),才能使用。函式的宣告通常是放在 標頭檔案 .h
裡面。
相反的,Python 可以直接定義或使用函式,不必事先宣告 (declaration)。
說文解字:引數 和 參數
以文章開始的 C程式範例來解釋:
void addByValue(int x) {
// ...
}
addByValue(num);
引數 (Argument) 是用於呼叫函式,例如 num 是 引數
參數 (Parameter) 是在函式的定義,例如 x 是 參數
但我在文章中,習慣都稱作 參數 。😅
Python 函式參數
在 Python程式碼,函式參數都是經由 引用 (reference)傳遞,稱作 「傳引用呼叫」 (Call by Reference)。在函式內對參數進行的任何改變,都可能會影響函式外的原來變數內容。
為什麼說 “可能” 會影響呢?
因為在 Python,所有的東西都是物件 (object)。
如果物件被創造出來,它的值 (value) 無法被改變,稱為 不可變動的物件 (Immutable object),常見的不可變動 (Immutable) 的型態,例如: 整數 (int)、浮點數 (float)、字串 (string)、元組 (tuple);
但如果它的值 (value) 可被改變,稱為 可變動的物件 (Mutable object),常見的 可變動 (Mutable) 的型態,如:串列 (list)、字典 (dict)、集合 (set)。
如果函式參數引用 (reference)對應可變動型態物件,自然可以改變。
def add_with_int(x):
x += 1
def modify_list(var):
var[0] = 10 # 改變第一個項目
var[1] = 20 # 改變第二個項目
var.append(60) # 增加一個項目在串列的尾端
num = 6
add_with_int(num)
print("num: ", num) # 呼叫函式後,num 依舊是 6
my_list = [1, 2, 3] # 串列
modify_list(my_list)
print(my_list) # 輸出: [10, 20, 3, 60]
在 Python 中,函數參數可有以下進階的變化:
這裡只做簡單的說文解字介紹,讓我們了解函數參數在 C 和 Python間的差異。